package com.xxx.redislock.controller;

import com.xxx.redislock.listener.SystemListener;
import com.xxx.redislock.service.Lock;
import com.xxx.redislock.service.RedisLockClient;
import com.xxx.redislock.utils.JodaUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * demo Controller
 */
@Validated
@Controller
@RequestMapping(value = "/", produces = "application/json;charset=utf-8")
public class DemoController {

    private static final Logger logger = LoggerFactory.getLogger(DemoController.class);

    @Autowired
    private RedisLockClient redisLockClient;

    /**
     * 系统启动时间戳
     */
    @RequestMapping("/versionNo")
    @ResponseBody
    public Map<String, String> versionNo(){
        logger.info("enter method versionNo().");
        Map<String, String> map = new HashMap<>();
        map.put("versionNo", SystemListener.versionNo);
        map.put("current", JodaUtil.currentTime());
        return map;
    }

    /**
     * 系统启动时间戳
     */
    @RequestMapping("/testLock")
    @ResponseBody
    public String testLock(String key){
        logger.info("enter method testLock(). key:{}", key);
        if(StringUtils.isEmpty(key)) {
            key = "test";
        }
        Lock lock = redisLockClient.getReentrantLock(key);
        try {
            boolean isLock = lock.tryLock(10, 30, TimeUnit.SECONDS);
            if (!isLock) {
                logger.error("加锁失败");
                return "fail";
            }

            logger.info("加锁成功");

           // 重复加锁
            this.reentrant(lock);

            logger.info("加锁成功后业务逻辑执行完成");
            return "success";
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
            logger.info("释放锁成功");
        }
    }


    private void reentrant(Lock lock) throws InterruptedException {
        logger.info("enter method reentrant()");
        try {
            boolean isLock = lock.tryLock(10, 30, TimeUnit.SECONDS);
            if (!isLock) {
                logger.error("重入加锁失败");
                return;
            }

            logger.info("重入加锁成功");
            logger.info("重入加锁成功后业务逻辑执行完成");
        } finally {
            lock.unlock();
            logger.info("释放重入锁成功");
        }
    }

}
